<?php

namespace App\Http\Controllers\Api;

use App\AuthorizerInfo;
use App\AvailableUrl;
use App\Enterprise;
use App\EnterpriseAdmin;
use App\EnterpriseUser;
use App\Files;
use App\Http\Controllers\Api\Admin\PlatformController;
use App\Http\Services\DomainManager;
use App\Http\Services\FileManager;
use App\Http\Services\MerchantManager;
use App\Http\Services\ToolsManager;
use App\PlatformConfig;
use App\User;
use Carbon\Carbon;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\HttpException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Exceptions\RuntimeException;
use Exception as E;
use File;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Log;
use Storage;

class WeChatThirdController extends Controller
{
    /**
     * 获取第三方平台配置信息
     * @return array
     */
    public static function getPlatformConfig(){
        $config=[
            'app_id'=>env('COMPONENT_APPID'),
            'secret'=>env('COMPONENT_SECRET'),
            'token'=>'f6effe41cbe6fc9e45feb2b88d907a3c2a0ecaf9',
            'aes_key'=>'3e42b4a03fa0b6783335d054f168f7ff989a69bec5c'
        ];
        $customConfig=PlatformConfig::first();
        if ($customConfig){
            if ($customConfig->component_appid){
                $config=[
                    'app_id'    =>$customConfig->component_appid,
                    'secret'    =>$customConfig->component_secret,
                    'token'     =>$customConfig->token,
                    'aes_key'   =>$customConfig->aes_key
                ];
            }
        }
        return $config;
    }

    public static function isFinish($enterpriseId){
        $record=AuthorizerInfo::whereEnterpriseId($enterpriseId)->first();
        return $record ? ($record->authorizer_refresh_token ? true : false) :false;
    }

    /**
     * 获取第三方平台access_token
     * @return array|null
     */
    public static function getPlatformAccessToken(){
        $openPlatform = Factory::openPlatform(self::getPlatformConfig());
        try{
            $token = $openPlatform->access_token->getToken();
        } catch (HttpException $e) {
            Log::error('HttpException:'.$e->getMessage());
            return null;
        }catch (InvalidArgumentException $e) {
            Log::error('InvalidArgumentException:'.$e->getMessage());
            return null;
        }catch (InvalidConfigException $e) {
            Log::error('InvalidConfigException:'.$e->getMessage());
            return null;
        }catch (RuntimeException $e) {
            Log::error('RuntimeException:'.$e->getMessage());
            return null;
        }catch (\Psr\SimpleCache\InvalidArgumentException $e) {
            Log::error('\Psr\SimpleCache\InvalidArgumentException:'.$e->getMessage());
            return null;
        }
        return $token;
    }

    /**@author cmj
     * 获取授权地址
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getPreAuthorizationUrl(Request $request){
        /** @var User $merchantUser */
        $merchantUser = MerchantManager::isLogin($request);
        if(!$merchantUser)
            return response()->json(['level' => 'error','message' => '请先登录！','data' => 'no_login']);

        $enterpriseInfo = MerchantManager::getMerchantInfoByUserId($merchantUser->id);
        if(!$enterpriseInfo)
            return response()->json(['level' => 'error','message' => '商家不存在']);

//        $authorizer_appid=$request->input('mp_appid') ?? '';
//
//        if (!$authorizer_appid)
//            return response()->json(['level' => 'error','message' => '请输入appid！','data' => []]);
//
//        $record=AuthorizerInfo::whereAuthorizerAppid($authorizer_appid)->first();
//        if (!$record){
//            $record=new AuthorizerInfo();
//            $record->enterprise_id=$merchantUser->enterprise_id;
//        }
//
//        $record->authorizer_appid        =$authorizer_appid;
//        $record->save();

        $enterpriseId=$merchantUser->enterprise_id;
        $enterpriseId=$enterpriseId+63793306;
        $config=self::getPlatformConfig();
        $openPlatform = Factory::openPlatform($config);
        $path=route('Api.WeChatThird.AuthorizationRedirectUri');
        $payload="?authorizer=$enterpriseId";
        $url=$openPlatform->getPreAuthorizationUrl($path.$payload); // 传入回调URI即可
        $data=[
            'url'=>$url
        ];
        return response()->json(['level'=>'success','message'=>'获取成功','data'=>$data]);
    }
    public function getPreAuthorizationPage(Request $request){
        /** @var User $merchantUser */
        $merchantUser = MerchantManager::isLogin($request);
        if(!$merchantUser)
            return response()->json(['level' => 'error','message' => '请先登录！','data' => 'no_login']);

        $enterpriseInfo = MerchantManager::getMerchantInfoByUserId($merchantUser->id);
        if(!$enterpriseInfo)
            return response()->json(['level' => 'error','message' => '商家不存在']);
        $domain=DomainManager::getDomain($request);
        $enterpriseId=EnterpriseAdmin::getEnterpriseId($merchantUser->id);
        $eId=$enterpriseId+63793306;
        $config=self::getPlatformConfig();
        Log::notice('PREAUTH MESSAGE:$domain=>'.$domain.';Config-APPID:'.$config['app_id']);
        $openPlatform = Factory::openPlatform($config);
        $path=route('Api.WeChatThird.AuthorizationRedirectUri');
        $payload="?authorizer=$eId";
        $url=$openPlatform->getPreAuthorizationUrl($path.$payload); // 传入回调URI即可
        return view('start',
            [
                'url'=>$url,
                'user_name'=>Enterprise::getEnterpriseName($enterpriseId),
                'is_finish'=>self::isFinish($enterpriseId)
            ]);
    }

    /**
     * 商家查看授权状态
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function checkAuthorizeStatus(Request $request){
        /** @var User $merchantUser */
        $merchantUser = MerchantManager::isLogin($request);
        if(!$merchantUser)
            return response()->json(['level' => 'error','message' => '请先登录！','data' => 'no_login']);

        $enterpriseInfo = MerchantManager::getMerchantInfoByUserId($merchantUser->id);
        if(!$enterpriseInfo)
            return response()->json(['level' => 'error','message' => '商家不存在']);

        $enterpriseId=EnterpriseAdmin::getEnterpriseId($merchantUser->id);
        $config=self::getPlatformConfig();

        $thisProgramRecord = AuthorizerInfo::whereEnterpriseId($enterpriseId)->first();
        $data=[
            'status'=>0,
            'status_name'=>'未授权',
        ];
        if (!$thisProgramRecord)
            return response()->json(['level' => 'success', 'message' => '未授权','data'=>$data]);

        try {
            $openPlatform = Factory::openPlatform($config);
            $miniProgram    = $openPlatform->miniProgram($thisProgramRecord->authorizer_appid, $thisProgramRecord->authorizer_refresh_token);
            $review = $miniProgram->code->getLatestAuditStatus();
        } catch (\Exception $e) {
            Log::error('getLatestAuditStatus　ERROR'.$e->getMessage());
            $review=false;
        }
        if ($review){
            if ($review['errcode']==0){
                if ($review['status']==0){
                    if ($thisProgramRecord->status==4){
                        $thisProgramRecord->status=5;
                        $thisProgramRecord->save();
                    }

                }
            }
        }

        $data['status']=$thisProgramRecord->status;
        $data['status_name']=AuthorizerInfo::getStatusName($thisProgramRecord->status);

        return response()
            ->json([
                'level'=>'success',
                'message'=>'success',
                'data'=>$data,
                'user'=>$merchantUser
            ]);
    }

    /**
     * 商家查看授权信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function checkAuthorizeInfo(Request $request){
        /** @var User $merchantUser */
        $merchantUser = MerchantManager::isLogin($request);
        if(!$merchantUser)
            return response()->json(['level' => 'error','message' => '请先登录！','data' => 'no_login']);

        $enterpriseInfo = MerchantManager::getMerchantInfoByUserId($merchantUser->id);
        if(!$enterpriseInfo)
            return response()->json(['level' => 'error','message' => '商家不存在']);

        $enterpriseId=EnterpriseAdmin::getEnterpriseId($merchantUser->id);

        $config=self::getPlatformConfig();
        $thisProgramRecord = AuthorizerInfo::whereEnterpriseId($enterpriseId)->first();

        if (!$thisProgramRecord)
            return response()->json(['level' => 'error', 'message' => '未授权','data'=>[]]);

        $openPlatform = Factory::openPlatform($config);

        try{
            $data = $openPlatform->getAuthorizer($thisProgramRecord->authorizer_appid);
        } catch (E $e){
            return response()->json(['level' => 'error', 'message' => '发生错误：'.$e->getMessage(),'data'=>[]]);
        }

        return response()
            ->json([
                'level'=>'success',
                'message'=>'success',
                'data'=>$data
            ]);
    }

    /**@author cmj
     * 获取授权页面
     * @param Request $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function getPreAuthorizationView(Request $request){
        $config=self::getPlatformConfig();
        $openPlatform = Factory::openPlatform($config);
        $url=$openPlatform->getPreAuthorizationUrl(route('Api.WeChatThird.AuthorizationRedirectUri'),['auth_type'=>2]); // 传入回调URI即可
        return view('start',['url'=>$url]);
    }

    /**@author cmj
     * 授权回调地址
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function AuthorizationRedirectUri(Request $request){
        /** @var User $merchantUser */
        $merchantUser   = MerchantManager::isLogin($request);
        $authorizer     = $request->input('authorizer') ?? false;
        $enterpriseId   = 0;
        if ($authorizer){
            $enterpriseId=$authorizer-63793306;
        }
        $config=$config=self::getPlatformConfig();
        $openPlatform = Factory::openPlatform($config);
        $authCode   =$request->input('auth_code');
        $result=$openPlatform->handleAuthorize($authCode);
        if ($result){
            if($result['authorization_info']){
               $authorizer_appid=$result['authorization_info']['authorizer_appid']          ?? '';
               $access_token    =$result['authorization_info']['authorizer_access_token']   ?? '';
               $refresh_token   =$result['authorization_info']['authorizer_refresh_token']  ?? '';
               $expires_in      =$result['authorization_info']['expires_in']                ?? 0 ;
               $func_info       =$result['authorization_info']['func_info']                 ?? '';
               $message='授权成功！现在可以关闭这个页面了';
               $record=AuthorizerInfo::whereAuthorizerAppid($authorizer_appid)->first();
               if (!$record){
                   $record=new AuthorizerInfo();
                   $record->enterprise_id=$enterpriseId;
               } else {
                   if ($enterpriseId != $record->enterprise_id){
                       $message='授权完成,小程序已转移至当前商家';
                   }
               }

               $record->authorizer_appid        =$authorizer_appid;
               $record->authorizer_access_token =$access_token;
               $record->authorizer_refresh_token=$refresh_token;
               $record->expires_in              =$expires_in;
               $record->func_info               =$func_info ? json_encode($func_info) : null;
               $record->auth_code               =$authCode;
               $record->enterprise_id           =$enterpriseId;
               $record->save();
               if ($record->status==0){
                   $record->status              =1;
                   $record->save();
               }

               return view('end',['message'=>$message]);
            }

        }
        return view('end',['message'=>'授权失败']);

    }

    /**
     * 完善小程序支付信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function setWechatPayConfig(Request $request){
        /** @var User $merchantUser */
        $merchantUser = MerchantManager::isLogin($request);
        if(!$merchantUser)
            return response()->json(['level' => 'error','message' => '请先登录！','data' => 'no_login']);
//        $mp_appid     = $request->input('mp_appid') ?? '';
        $mch_id       = $request->input('mch_id');
        $key          = $request->input('key');
        $cert_file_id = $request->input('cart_file_id');
        $key_file_id  = $request->input('key_file_id');
//        if (!$mp_appid)
//            return response()->json(['level'=>'error','message'=>'请输入小程序appid']);
        if (!$mch_id)
            return response()->json(['level'=>'error','message'=>'请输入支付商户号']);
        if (!$key)
            return response()->json(['level'=>'error','message'=>'请输入支付API密钥']);

        $enterprise   = EnterpriseAdmin::whereUserId($merchantUser->id)->first();

        if (!$enterprise || $enterprise->enterprise_id==0)
            return response()->json(['level'=>'error','message'=>'管理员才可以设置哦']);

        $record = AuthorizerInfo::whereEnterpriseId($enterprise->enterprise_id)
            ->whereNotNull('authorizer_appid')
            ->whereNotNull('authorizer_refresh_token')
            ->first();
        if (!$record)
            return response()->json(['level'=>'error','message'=>'请先授权小程序']);
        $config=AvailableUrl::whereEnterpriseId($enterprise->enterprise_id)
            ->whereMiniprogramAppid($record->authorizer_appid)
            ->first();
        if (!$config){
            $config=new AvailableUrl();
            $config->enterprise_id      =$enterprise->enterprise_id;
            $config->miniprogram_appid  =$record->authorizer_appid;
        }
        $config->wechatpay_mchid    =$mch_id;
        if (strlen($key)>=32)
            $config->wechatpay_key      =$key;

        if ($cert_file_id){
            $thisFile=Files::whereId($cert_file_id)->first();
            $config->wechatpay_certificate_cert_name = $thisFile ? $thisFile->file_md5 : '';
        }

        if ($key_file_id){
            $thisFile=Files::whereId($key_file_id)->first();
            $config->wechatpay_certificate_key_name = $thisFile ? $thisFile->file_md5 : '';
        }

        $config->save();
        return response()->json(['level'=>'success','message'=>'填写成功']);
    }
    public function getWechatPayConfig(Request $request){
        /** @var User $merchantUser */
        $merchantUser = MerchantManager::isLogin($request);
        if(!$merchantUser)
            return response()->json(['level' => 'error','message' => '请先登录！','data' => 'no_login']);

        $enterprise   = EnterpriseAdmin::whereUserId($merchantUser->id)->first();

        if (!$enterprise || $enterprise->enterprise_id==0)
            return response()->json(['level'=>'error','message'=>'管理员才能操作']);

        $record = AuthorizerInfo::whereEnterpriseId($enterprise->enterprise_id)
            ->whereNotNull('authorizer_appid')
            ->whereNotNull('authorizer_refresh_token')
            ->first();
        if (!$record)
            return response()->json(['level'=>'error','message'=>'请先授权小程序']);
        $config=AvailableUrl::whereEnterpriseId($enterprise->enterprise_id)
            ->whereMiniprogramAppid($record->authorizer_appid)
            ->first();
        if (!$config){
            $config=new AvailableUrl();
            $config->enterprise_id      =$enterprise->enterprise_id;
            $config->miniprogram_appid  =$record->authorizer_appid;
            $config->save();
        }
        $config->wechatpay_key=ToolsManager::coverString($config->wechatpay_key);
        return response()->json(['level'=>'success','message'=>'获取成功','data'=>$config]);
    }

    /**
     * 上传证书
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function uploadCert(Request $request){
        $uploadFile  = $request->file('file');

        if(!$request->hasFile('file'))
            return response()->json(['level'=>'error','message'=>'证书不存在']);

        if(!$uploadFile->isValid())
            return response()->json(['level'=>'error','message'=>'证书上传失败']);

        $fileName = $uploadFile->getClientOriginalName();

        $fileMd5 = md5_file($uploadFile);
        $fileType = File::extension($fileName);
        if ($fileType != 'pem')
            return response()->json(['level'=>'error','message'=>'请上传pem格式的证书']);
        $disk='local';
        $toDirPath = 'cert';
        $toFilePath = $toDirPath.'/'.$fileMd5.'.'.$fileType;
        if(!Storage::disk($disk)->exists($toDirPath)){
            Storage::disk($disk)->makeDirectory($toDirPath);
        }
        try{
            if(!Storage::disk($disk)->exists($toFilePath)){
                Storage::disk($disk)->put($toFilePath,File::get($uploadFile));
            }
        } catch (E $exception){
            Log::error('uploadCert:'.$exception->getMessage());
            return response()->json(['level'=>'error','message'=>'上传发生错误：'.$exception->getMessage(),'data'=>'']);
        }

        File::delete($uploadFile);
        $fileSize = Storage::disk($disk)->size($toFilePath);
        $mimeType = Storage::disk($disk)->mimeType($toFilePath);

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize)->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $fileName;
            $files->file_url  = $toDirPath;
            $files->file_type = '.'.$fileType;
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize;
            $files->file_ext  = $mimeType;
            $files->disk      = $disk;
            $files->save();
        }

        return response()->json(['level'=>'success','message'=>'上传成功','data'=>$files]);
    }

    public function uploadKey(Request $request){
        $uploadFile  = $request->file('file');

        if(!$request->hasFile('file'))
            return response()->json(['level'=>'error','message'=>'证书不存在']);

        if(!$uploadFile->isValid())
            return response()->json(['level'=>'error','message'=>'证书上传失败']);

        $fileName = $uploadFile->getClientOriginalName();

        $fileMd5 = md5_file($uploadFile);
        $fileType = File::extension($fileName);
        if ($fileType != 'pem')
            return response()->json(['level'=>'error','message'=>'请上传pem格式的证书']);
        $disk='local';
        $toDirPath = 'key';
        $toFilePath = $toDirPath.'/'.$fileMd5.'.'.$fileType;
        if(!Storage::disk($disk)->exists($toDirPath)){
            Storage::disk($disk)->makeDirectory($toDirPath);
        }
        try{
            if(!Storage::disk($disk)->exists($toFilePath)){
                Storage::disk($disk)->put($toFilePath,File::get($uploadFile));
            }
        } catch (E $exception){
            Log::error('uploadCert:'.$exception->getMessage());
            return response()->json(['level'=>'error','message'=>'上传发生错误：'.$exception->getMessage(),'data'=>'']);
        }

        File::delete($uploadFile);
        $fileSize = Storage::disk($disk)->size($toFilePath);
        $mimeType = Storage::disk($disk)->mimeType($toFilePath);

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize)->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $fileName;
            $files->file_url  = $toDirPath;
            $files->file_type = '.'.$fileType;
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize;
            $files->file_ext  = $mimeType;
            $files->disk      = $disk;
            $files->save();
        }

        return response()->json(['level'=>'success','message'=>'上传成功','data'=>$files]);
    }


}
